package 线程池.unsafe实现自旋锁;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * 
 * 文章参考： 绝绝子
 * https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html
 * 
 * @author caihe
 * @date 2021/10/20 13:35
 */
public class UnsafeLock {

    private volatile int state;

    private static long stateOffset;

    private static Unsafe unsafe;

    public UnsafeLock() {
        this.state = 0;
    }

    static {
        try {
            // 通过反射获取Unsafe类
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
            // 获取 state成员属性相对UnsafeLock对象内存地址的偏移量
            stateOffset = unsafe.objectFieldOffset(UnsafeLock.class.getDeclaredField("state"));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 尝试更新
     *
     * @param expect 期望值 - 旧值
     * @param update 更新值
     * @return 是否更新成功
     */
    private boolean compareAndSetState(int expect, int update) {
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    public void lock() {
        while (true) {
            if (state == 0) {
                if (compareAndSetState(state, 1)){
                    return;
                }
            }
        }
    }
    
    public void unLock() {
        while (true) {
            if (state != 0) {
                if (compareAndSetState(1, 0)){
                    return;
                }
            }
        }
    }

}
